{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Cheating coin toss quantum circuit\n",
    "In this exercise we create a quantum circuit quantum circuit that tweaks the probabilistic nature of a single qubit in superposition. Like before we put the qubit in superposition $|\\psi\\rangle = \\left(|0\\rangle+|1\\rangle\\right)/\\sqrt{2}.$  \n",
    "We then add an additional Ry (rotation around the Y axis) gate, which pushes the Bloch vector $\\pi/8$ closer to $|1\\rangle$. we tweak the odds in favor of $|1\\rangle$. The expected outcome is now $|0\\rangle$ ~ 33% and $|1\\rangle$ with a 66% probability.\n",
    "The result is displayed as a numeric readout, as a bar diagram.\n",
    "\n",
    "In this exercise we introduce the Ry gate, which rotates a qubit around the y-axis.\n",
    "```\n",
    "        ┌────────────┐\n",
    "q_0: |0>┤ Ry(0.3927) ├\n",
    "        └────────────┘\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Import the required libraries."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "from qiskit import QuantumCircuit, execute, Aer\n",
    "\n",
    "# Import Blochsphere visualization\n",
    "from qiskit.visualization import plot_bloch_multivector, plot_histogram\n",
    "\n",
    "# We also need to use pi in our gate input\n",
    "from math import pi\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "As we will be using the Bloch sphere visualization (`plot_bloch_multivector`) a bit, here's a quick function that calculates the state vector ($|\\psi\\rangle$) for the circuit to let you display the Bloch vector for any given state."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "def get_psi(circuit): \n",
    "    global psi\n",
    "    backend = Aer.get_backend('statevector_simulator') \n",
    "    psi = execute(circuit, backend).result().get_statevector(circuit)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Create an empty quantum circuit."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "qc = QuantumCircuit(1,1)\n",
    "\n",
    "print(qc)\n",
    "\n",
    "# Display the Bloch sphere\n",
    "get_psi(qc)\n",
    "plot_bloch_multivector(psi)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Add a Hadamard (super position) gate to the quantum circuit. This puts the qubit in a superposition: $|\\psi\\rangle = \\left(|0\\rangle+|1\\rangle\\right)/\\sqrt{2}.$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "qc.h(0)\n",
    "print(qc)\n",
    "\n",
    "# Display the Bloch sphere\n",
    "get_psi(qc)\n",
    "plot_bloch_multivector(psi)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Now, let's rotate the Bloch vector vector $\\pi$/8 radians closer to $|1\\rangle$ by adding a Y rotation gate."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "qc.ry(pi/8,0) \n",
    "#Move the Bloch vector pi/8 radians closer to |1>. \n",
    "print(qc)\n",
    "\n",
    "# Display the Bloch sphere\n",
    "get_psi(qc)\n",
    "plot_bloch_multivector(psi)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "And finally add the measurement:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "qc.measure(0,0)\n",
    "print(qc)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Set the backend to a local simulator."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "backend = Aer.get_backend('qasm_simulator')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Create a quantum job for the circuit, the selected backend, that runs a number of shots to simulate a sequence of coin tosses. Run the job and display the results. Display the result as a histogram. The slight tweak of the Bloch vector towards |1> turns out to have a massive result in that ~70% of the coin tosses are now |1>."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "job = execute(qc, backend, shots=1000)\n",
    "result = job.result()\n",
    "counts  = result.get_counts(qc)\n",
    "print(counts)\n",
    "plot_histogram(counts)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
